package com.ezlcp.user.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ezlcp.commons.base.db.BaseDao;
import com.ezlcp.commons.base.db.BaseService;
import com.ezlcp.commons.constant.LanguageEnum;
import com.ezlcp.commons.model.SysUser;
import com.ezlcp.commons.service.impl.SuperServiceImpl;
import com.ezlcp.commons.tool.Encrypt;
import com.ezlcp.commons.tool.IdGenerator;
import com.ezlcp.commons.tool.StringUtils;
import com.ezlcp.commons.utils.ContextUtil;
import com.ezlcp.commons.utils.GoogleAuthenticator;
import com.ezlcp.user.entity.Company;
import com.ezlcp.user.entity.Group;
import com.ezlcp.user.entity.User;
import com.ezlcp.user.enums.StatusEnum;
import com.ezlcp.user.enums.UserTypeEnum;
import com.ezlcp.user.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * [用户表]业务服务类
 */
@Service
public class UserServiceImpl extends SuperServiceImpl<UserMapper, User> implements BaseService<User> {
    @Resource
    CompanyServiceImpl companyService;
    @Lazy
    @Autowired
    MenuServiceImpl menuService;
    @Lazy
    @Autowired
    SerialNoServiceImpl serialNoService;
    @Lazy
    @Autowired
    SettingsServiceImpl settingsService;
    @Lazy
    @Autowired
    LogService logService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private GroupServiceImpl groupService;

    /***
     * @description: 根据当前公司ID查询所有员工
     * @author Weixuan LONG
     * @date 2022/5/30 14:35
     */
    public List<User> getByTenantId() {
        QueryWrapper<User> wrapper = Wrappers.query();
        wrapper.lambda()
                .eq(User::getTenantId, ContextUtil.getCurrentTenantId())
                .eq(User::getUserType, UserTypeEnum.User.getValue())
                .eq(User::getStatus, StatusEnum.enable);
        return this.findAll(wrapper);
    }


    /**
     * @param username 用户名
     * @description: 登录校验
     * @author ou zhen
     * @date 2022/5/9 10:12
     */
    public User getByUserName(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", username);
        return userMapper.selectOne(wrapper);
    }

    /**
     * @param newUser 需注册用户
     * @return 已注册用户
     * @description: 注册用户
     * @author ou zhen
     * @date 2022/5/9 10:12
     */
    public User registerUser(User newUser) {
        String tenantId = ContextUtil.getCurrentTenantId();
        newUser.setTenantId(tenantId);
        if (ObjectUtil.isEmpty(newUser.getLanguage())) {
            newUser.setLanguage(LanguageEnum.zh_TW.name());
        }
        // 注册时自动生成Google验证密钥
        newUser.setSecretKey(GoogleAuthenticator.generateSecretKey());
        // 默认未绑定Google验证
        newUser.setIsBind((short) 0);
        insert(newUser);
        String encryptionPassword = Encrypt.getMd5Password(newUser.getUserId(), newUser.getPassword());
        newUser.setPassword(encryptionPassword);
        update(newUser);
        //同时新增角色
        String[] roleIds = newUser.getGroupIds();
        if (roleIds.length > 0) {
            groupService.addUserGroups(newUser.getPkId(), StringUtils.join(roleIds, ","));
        }
        return newUser;
    }


    /***
     * @description: 注册公司
     * @param company 需注册公司
     * @author ou zhen
     * @date 2022/5/9 10:12
     */
    @Transactional(rollbackFor = Exception.class)
    public void registerCompany(Company company) {
        User newUser = new User();
        newUser.setUserName(company.getUserName());
        newUser.setPassword(company.getPassword());
        newUser.setStatus(StatusEnum.enable);
        newUser.setLanguage(LanguageEnum.zh_TW.name());
        newUser.setUserType((short) UserTypeEnum.Admin.getValue());
        // 注册时自动生成Google验证密钥
        newUser.setSecretKey(GoogleAuthenticator.generateSecretKey());
        // 默认未绑定Google验证
        newUser.setIsBind((short) 0);
        newUser.setUserId(IdGenerator.getIdStr());
        String encryptionPassword = Encrypt.getMd5Password(newUser.getUserId(), newUser.getPassword());
        newUser.setPassword(encryptionPassword);
        company.setStatus(StatusEnum.enable);
        company.setUserId(newUser.getUserId());
        companyService.insert(company);
        newUser.setTenantId(company.getTenantId());
        newUser.setName(company.getName());
        insert(newUser);
        menuService.getTenantAllMenus(company.getTenantId());
        serialNoService.getByTenant(company.getTenantId());
        settingsService.getByTenant(company.getTenantId());
        logService.saveSystemLog("用户", "/registerCompany", newUser.getPkId(), JSON.toJSONString(newUser));
        logService.saveSystemLog("公司", "/registerCompany", company.getPkId(), JSON.toJSONString(company));
    }

    /**
     * @param name 用户名
     * @return 返回用户是否重复，true/false
     * @description: 验证用户是否重复
     * @author ou zhen
     * @date 2022/5/9 10:12
     */
    public boolean checkName(String name) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", name);
        User user = userMapper.selectOne(wrapper);
        return ObjectUtil.isNotNull(user);
    }

    /**
     * @param tenantId 公司ID
     * @return 员工数
     * @description: 统计员工
     * @author ou zhen
     * @date 2022/5/9 10:12
     */
    public Long countStaff(String tenantId) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("tenant_id", tenantId);
        wrapper.eq("status", StatusEnum.enable.name());
        wrapper.eq("user_type", UserTypeEnum.User.getValue());
        return userMapper.selectCount(wrapper);
    }

    /**
     * @param user 用户
     * @return com.hkyctech.commons.model.SysUser
     * @description: 转换User类型为SysUser类型
     * @author Elwin ZHANG
     * @date 2022/5/7 10:12
     */
    public SysUser convert2SysUser(User user) {
        if (user == null) {
            return null;
        }
        SysUser sysUser = new SysUser();
        sysUser.setAccount(user.getUserName());
        sysUser.setUserId(user.getUserId());
        sysUser.setPassword(user.getPassword());
        sysUser.setGender(user.getGender());
        sysUser.setFullName(user.getName());
        sysUser.setMobile(user.getMobileNo());
        sysUser.setStatus(user.getStatus().name());
        sysUser.setEmail(user.getEmail());
        sysUser.setIsLock(user.getIsLock());
        sysUser.setLanguage(user.getLanguage());
        sysUser.setTenantId(user.getTenantId());
        sysUser.setUserCode(user.getUserCode());
        var type = UserTypeEnum.valueOf(user.getUserType());
        sysUser.setUserType(type.name());
        sysUser.setEnglishName(user.getEnName());
        List<Group> listRoles = groupService.getUserGroups(user.getUserId());
        List<String> listRoleIds = listRoles.stream().map(Group::getGroupId).collect(Collectors.toList());
        sysUser.setRoles(listRoleIds);
        return sysUser;
    }


    /***
     * @description 修改用户时判断用户名是否存在
     * @param user 用户对象
     * @return boolean
     * @author Elwin ZHANG
     * @date 2022/7/27 13:35
     */
    public boolean checkUserName(User user) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", user.getUserName());
        wrapper.ne("user_id", user.getUserId());
        Long count = userMapper.selectCount(wrapper);
        return count == 0;
    }

    /**
     * @param user      用户
     * @param saveRoles 是否改变用户的角色信息
     * @description: 更新用户信息
     * @author Ou Zhen
     * @date 2022/5/10 16:25
     */
    public Boolean updateUser(User user, boolean saveRoles) {
        user.setPassword(null);
        if (!checkUserName(user)) {
            return false;
        }
        UpdateWrapper<User> updateWrapper = Wrappers.update();
        updateWrapper.lambda()
                .eq(User::getUserId, user.getUserId());
        user.setSeq(user.getSeq() + 1);
        boolean result = this.update(user, updateWrapper);
        //如果不改变用户角色信息，则退出
        if (!saveRoles) {
            return result;
        }
        //更新用户的角色
        String[] roles = user.getGroupIds();
        String userId = user.getPkId();
        if (roles == null || roles.length == 0) {
            groupService.deleteUserGroups(userId);
        } else {
            String ids = StringUtils.join(roles, ",");
            groupService.editUserGroups(userId, ids);
        }
        return result;
    }

    /***
     * @description: 判断传参是否为空
     * @param user 传入用户
     * @return java.lang.String 当字符串长度为0，则无误；否则有误
     * @author ou zhen
     * @date 2022/5/11 17:49
     */
    public String checkUserField(User user, Integer integer) {
        if (StringUtils.isEmpty(user.getUserName())) {
            return "user.userNameNotNull";
        }
        if (StringUtils.isEmpty(user.getPassword())) {
            return "user.passwordNotNull";
        }
        if (ObjectUtil.isEmpty(user.getUserType())) {
            return "user.userType";
        }
        if (ObjectUtil.isEmpty(user.getStatus())) {
            return "user.userState";
        }
        if (ObjectUtil.isEmpty(user.getEntryDate())) {
            return "user.entryDate";
        }
        if (StringUtils.isEmpty(user.getName())) {
            return "common.inputName";
        }
        if (ObjectUtil.isEmpty(user.getGender())) {
            return "customer.selectSex";
        }
        if (StringUtils.isEmpty(user.getUserCode())) {
            return "user.userCode";
        }
        return "";
    }

    /***
     * @description: 判断传参是否为空
     * @param company 传入公司
     * @return java.lang.String 当字符串长度为0，则无误；否则有误
     * @author ou zhen
     * @date 2022/5/11 17:49
     */
    public String checkCompanyField(Company company) {
        if (StringUtils.isEmpty(company.getUserName())) {
            return "user.userNameNotNull";
        }
        if (StringUtils.isEmpty(company.getPassword())) {
            return "user.passwordNotNull";
        }
        if (StringUtils.isEmpty(company.getName())) {
            return "company.inputNameChi";
        }
        if (StringUtils.isEmpty(company.getEnName())) {
            return "company.inputNameEn";
        }
        if (StringUtils.isEmpty(company.getLicenseNo())) {
            return "user.licenseNo";
        }
        if (ObjectUtil.isEmpty(company.getTimeLimit())) {
            return "user.timeLimit";
        }
        if (ObjectUtil.isEmpty(company.getAccountLimit())) {
            return "user.accountLimit";
        }
        return "";
    }

    /***
     * @description: 上级修改下级密码
     * @param newPassword 新密码
     * @param userId 用户ID
     * @return java.lang.String
     * @author ou zhen
     * @date 2022/5/13 16:23
     */
    public String updatesLowerPassWord(String newPassword, String userId) {
        if (StringUtils.isEmpty(userId)) {
            return "user.beModifiedUserIdNoNull";
        }
        if (StringUtils.isEmpty(newPassword)) {
            return "user.inputNewPassword";
        }
        User updateUser = this.getById(userId);
        if (!checkResetPasswordAuth(updateUser)) {
            logService.saveSystemLog("上级修改下级密码", "非法操作", null, null);
            return "common.insufficientPrivileges";
        }

        String newPw = Encrypt.getMd5Password(updateUser.getUserId(), newPassword);
        updateUser.setPassword(newPw);
        updateUser.setSeq(updateUser.getSeq() + 1);
        this.update(updateUser);
        User oldEnt = this.getById(updateUser.getUserId());
        //记录日志
        String detail = "old:" + JSON.toJSONString(oldEnt) + ",new:" + JSON.toJSONString(updateUser);
        logService.saveSystemLog("用户", "updatesLowerPassWord", updateUser.getPkId(), detail);
        return "";
    }

    /***
     * @description 判断当前用户是否具备重置某用户密码的权限
     * @param updateUser 要修改的用户
     * @return boolean
     * @author Elwin ZHANG
     * @date 2023/2/8 15:13
     */
    private boolean checkResetPasswordAuth(User updateUser) {
        var curUser=   ContextUtil.getCurrentUser();
        String curTenantId = curUser.getTenantId();
        if (curUser.isPlatformUser()) {
            //当前用户为普通员工
            if (curUser.isStaff()) {
                if (!curTenantId.equals(updateUser.getTenantId()) || updateUser.isAdmin()) {
                    return false;
                }
            }
            //当前用户为租户管理员
            if (curUser.isAdmin()) {
                if (!curTenantId.equals(updateUser.getTenantId())) {
                    return false;
                }
            }
        } else {
            //当前用户为平台员工
            if (!curUser.isAdmin()) {
                if (updateUser.isSuperAdmin()) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public BaseDao<User> getRepository() {
        return userMapper;
    }
}